﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace testqwe
{
    class Parallelogram
    {
        //平行四边形块
        int longLength;
        int width;
        int[] diameter;
        double[] value;
        Stripe[] stripe;
        int[,] F;
        int[,] G;
         public  int[,] Q;
        bool[,] P;
        double xsectionvalue;
        double ysectionvalue;
        public double revalue;
        public int[] result;
        public List<int[]> pattern;
        public int directiontype;
        List<int[]> xsectionpattern;
        List<int[]> ysectionpattern;

        public Parallelogram(int l, int w, int[] d, double[] v, Stripe[] ps)
        {
            longLength = l;
            width = (int)(w * Constant.THIRD_OF_SQRT_THREE * 2);
            diameter = d;
            value=v;
            int max = (l > width )? l : width;
            stripe = ps;
            F = new int[longLength+1, width+1];
            G = new int[longLength + 1, width+1];
            Q = new int[longLength+1, width+1];
            P = new bool[longLength+1, width+1];
            pattern = new List<int[]>();
            directiontype = -1;
        }

        public void start()
        {
            complexpattern(1);
        }


        //平行四边形块的排样
        private void complexpattern(int patterntype)
        {
            result = new int[Constant.BLK_NUM];
            //平行四边形块中条带都是X向的或Y向，只有一个段
            if (patterntype == 1)
            {
                int[] n1 = complexxsection(longLength);
                int[] n2 = complexysection(longLength);
                if (xsectionvalue > ysectionvalue)
                {
                    result = n1;
                    revalue = xsectionvalue;
                    directiontype = 0;
                    pattern = xsectionpattern;
                }
                else
                {
                    result = n2;
                    directiontype = 1;
                    revalue = ysectionvalue;
                    pattern = ysectionpattern;
                }
            }
            //平行四边形块中采用T形排样方式，有两个段
            else if (patterntype==2)
            {
                double max = 0.0;
                int[] m1 = new int[Constant.BLK_NUM];
                int[] m2 = new int[Constant.BLK_NUM];
                for (int i = 0; i < longLength; i++)
                {
                    int[] n1 = complexxsection(i);
                    int[] n2 = complexysection(longLength-i);
                    if (xsectionvalue + ysectionvalue > max)
                    {
                        max = xsectionvalue + ysectionvalue;
                        m1 = n1;
                        m2 = n2;
                    }
                }
                revalue = max;
                for (int j = 0; j < Constant.BLK_NUM; j++)
                {
                    result[j] = m1[j] + m2[j];
                }
            }
        }
        
       
         

       
        //动态规划算法实现X向的平行四边形块的排样
        private int[] complexxsection(int xlength)
        {
            xsectionpattern = new List<int[]>();
            
            int[] result = new int[Constant.BLK_NUM];
            double[] h = new double[width + 1];
            List<int>[] pid = new List<int>[width + 1];
            List<int>[] prow = new List<int>[width + 1];
            for (int p = 0; p <= width; p++)
            {
                double maxvalue = 0.0;
                int id = -1;
                int row=-1;
                int inwid = 0;
                for (int t = 0; t < Constant.BLK_NUM; t++)
                {
                    if (p < stripe[t].width[0]) continue;
                    for (int q = 0; q < Constant.ROW; q++)
                    {
                        if (p < stripe[t].width[q]) break;
                        int nwidth = (int)stripe[t].width[q] + 1;
                        double n = stripe[t].u[q, xlength]*value[t] + h[p - nwidth];
                        if (n > maxvalue)
                        {
                            maxvalue = n;
                            id = t;
                            row = q;
                            inwid = nwidth;
                        }
                    }
                }
                if (maxvalue > h[p]&&id!=-1)
                {
                    h[p] = maxvalue;
                    pid[p] = new List<int>();
                    prow[p] = new List<int>();
                    List<int> tempid = pid[p - inwid];
                    List<int> temprow = prow[p - inwid];
                    if (tempid != null && temprow != null)
                    {
                        int n = tempid.Count;
                        for (int i = 0; i < n; i++)
                        {
                            pid[p].Add(tempid[i]);
                            prow[p].Add(temprow[i]);
                        }
                        pid[p].Add(id);
                        prow[p].Add(row);
                    }
                    else 
                    {
                        pid[p].Add(id);
                        prow[p].Add(row);
                    }
                }
            }
            xsectionvalue = h[width];
            if (pid[width] != null)
            {
                int m = pid[width].Count;
                for (int i = 0; i < m; i++)
                {
                    int[] tempresult = new int[4];
                    int n = pid[width][i];
                    int r = prow[width][i];
                    int amount = stripe[n].u[r, xlength];
                    result[n] += amount;
                    tempresult[0] = n;
                    tempresult[1] = r+1;
                    tempresult[2] = amount;
                    tempresult[3] = (int)(stripe[n].width[r]+0.999);
                    xsectionpattern.Add(tempresult);
                }
            }
            return result;
        }

        //动态规划算法实现Y向的平行四边形块的排样
        private int[] complexysection(int xlength)
        {
            ysectionpattern = new List<int[]>();
            
            int[] result = new int[Constant.BLK_NUM];
            double[] h = new double[xlength + 1];
            List<int>[] pid = new List<int>[xlength + 1];
            List<int>[] prow = new List<int>[xlength + 1];
            for (int p = 0; p <= xlength; p++)
            {
                double maxvalue = 0.0;
                int id = -1;
                int row = -1;
                int inwid = 0;
                for (int t = 0; t < Constant.BLK_NUM; t++)
                {
                    if (p < stripe[t].width[0]) continue;
                    for (int q = 0; q < Constant.ROW; q++)
                    {
                        if (p < stripe[t].width[q]) break;
                        int nwidth = (int)stripe[t].width[q] + 1;
                        double n = stripe[t].u[q, width] * value[t] + h[p - nwidth];
                        if (n > maxvalue)
                        {
                            maxvalue = n;
                            id = t;
                            row = q;
                            inwid = nwidth;
                        }
                    }
                }
                if (maxvalue > h[p] && id != -1)
                {
                    h[p] = maxvalue;
                    pid[p] = new List<int>();
                    prow[p] = new List<int>();
                    List<int> tempid = pid[p - inwid];
                    List<int> temprow = prow[p - inwid];
                    if (tempid != null && temprow != null)
                    {
                        int n = tempid.Count;
                        for (int i = 0; i < n; i++)
                        {
                            pid[p].Add(tempid[i]);
                            prow[p].Add(temprow[i]);
                        }
                        pid[p].Add(id);
                        prow[p].Add(row);
                    }
                    else
                    {
                        pid[p].Add(id);
                        prow[p].Add(row);
                    }

                }
            }
            ysectionvalue = h[xlength];
            if (pid[xlength] != null)
            {
                int m = pid[xlength].Count;
                for (int i = 0; i < m; i++)
                {
                    int[] tempresult = new int[4];
                    int n = pid[xlength][i];
                    int r = prow[xlength][i];
                    int amount = stripe[n].u[r, width];
                    result[n] +=amount;
                    tempresult[0] = n;
                    tempresult[1] = r+1;
                    tempresult[2] = amount;
                    tempresult[3] = (int)(stripe[n].width[r] + 0.999);
                    ysectionpattern.Add(tempresult);
                }
            }
            return result;
        }
        
    }
}
